import { Injectable, Logger, OnModuleInit } from "@nestjs/common";
import { Cron, CronExpression } from "@nestjs/schedule";
import { DataSource } from "typeorm";
import { CasinoDiceRoundService } from "./casino-dice-round.service";
import { CasinoChibiRoundService } from "./casino-chibi-round.service";
import { CasinoSettlementService } from "./casino-settlement.service";
import { GameType } from "../entities";
import {
  CasinoDiceRound,
  DiceRoundStatus,
} from "../entities/casino-dice-round.entity";
import {
  CasinoChibiRound,
  ChibiRoundStatus,
} from "../entities/casino-chibi-round.entity";

@Injectable()
export class CasinoSchedulerService implements OnModuleInit {
  private readonly logger = new Logger(CasinoSchedulerService.name);
  private isProcessing = false; // 防止重复执行
  private isDiceProcessing = false; // 防止大小玩法重复执行
  private isChibiProcessing = false; // 防止赤壁玩法重复执行

  constructor(
    private readonly dataSource: DataSource,
    private readonly diceRoundService: CasinoDiceRoundService,
    private readonly chibiRoundService: CasinoChibiRoundService,
    private readonly settlementService: CasinoSettlementService
  ) {}

  onModuleInit() {
    // 检查是否禁用定时任务
    const disableScheduler = process.env.DISABLE_CASINO_SCHEDULER === "true";

    if (!disableScheduler) {
      this.logger.log("🔄 娱乐城定时任务调度器启动成功！");
      // 启动时执行重启后的期数恢复和检查
      this.handleServiceRestart();
    }
  }

  /**
   * 处理服务重启后的期数恢复和检查
   */
  private async handleServiceRestart(): Promise<void> {
    try {
      this.logger.log("🔄 开始处理服务重启后的期数恢复...");

      // 1. 重置当前下注中期数的时间
      await this.resetCurrentBettingRoundsTime();

      // 2. 恢复过期未结算的期数
      await this.recoverExpiredUnsettledRounds();

      // 3. 确保有当前活跃期数
      await this.ensureActiveRoundsExist();

      // 4. 检查并处理重启期间可能错过的定时任务
      await this.handleMissedScheduledTasks();

      this.logger.log("✅ 服务重启后的期数恢复完成");
    } catch (error: any) {
      this.logger.error("❌ 服务重启后期数恢复失败:", error?.message || error);
    }
  }

  /**
   * 重置当前下注中期数的时间
   * 将开始时间修改为当前时间，结束时间修改为10分钟后
   */
  private async resetCurrentBettingRoundsTime(): Promise<void> {
    try {
      this.logger.log("🔄 开始重置当前下注中期数的时间...");

      const now = new Date();
      const newEndTime = new Date(now.getTime() + 10 * 60 * 1000); // 当前时间 + 10分钟

      // 重置大小玩法的当前下注中期数时间
      const currentDiceRound = await this.diceRoundService.getCurrentRound();
      if (
        currentDiceRound &&
        currentDiceRound.status === DiceRoundStatus.BETTING
      ) {
        await this.diceRoundService.updateRoundTimes(
          currentDiceRound.id,
          now,
          newEndTime
        );
        this.logger.log(
          `✅ 重置大小期数 ${
            currentDiceRound.id
          } 时间: 开始=${now.toISOString()}, 结束=${newEndTime.toISOString()}`
        );
      } else if (currentDiceRound) {
        this.logger.log(
          `ℹ️ 大小期数 ${currentDiceRound.id} 状态为 ${currentDiceRound.status}，不是下注中状态，跳过时间重置`
        );
      }

      // 重置赤壁玩法的当前下注中期数时间
      const currentChibiRound = await this.chibiRoundService.getCurrentRound();
      if (
        currentChibiRound &&
        currentChibiRound.status === ChibiRoundStatus.BETTING
      ) {
        await this.chibiRoundService.updateRoundTimes(
          currentChibiRound.id,
          now,
          newEndTime
        );
        this.logger.log(
          `✅ 重置赤壁期数 ${
            currentChibiRound.id
          } 时间: 开始=${now.toISOString()}, 结束=${newEndTime.toISOString()}`
        );
      } else if (currentChibiRound) {
        this.logger.log(
          `ℹ️ 赤壁期数 ${currentChibiRound.id} 状态为 ${currentChibiRound.status}，不是下注中状态，跳过时间重置`
        );
      }

      this.logger.log("✅ 当前下注中期数时间重置完成");
    } catch (error: any) {
      this.logger.error(
        "❌ 重置当前下注中期数时间失败:",
        error?.message || error
      );
    }
  }

  /**
   * 处理重启期间可能错过的定时任务
   */
  private async handleMissedScheduledTasks(): Promise<void> {
    try {
      this.logger.log("🔄 检查重启期间可能错过的定时任务...");

      const now = new Date();

      // 检查大小玩法是否有需要处理的期数
      const currentDiceRound = await this.diceRoundService.getCurrentRound();
      if (currentDiceRound) {
        const timeLeft = currentDiceRound.endTime.getTime() - now.getTime();

        // 如果当前期数已经过期或即将过期（剩余时间少于1分钟），执行轮转
        if (timeLeft <= 60000) {
          this.logger.log("⚠️ 发现大小玩法期数已过期或即将过期，执行轮转");
          await this.handleDiceRoundRotation();
        }
      }

      // 检查赤壁玩法是否有需要处理的期数
      const currentChibiRound = await this.chibiRoundService.getCurrentRound();
      if (currentChibiRound) {
        const timeLeft = currentChibiRound.endTime.getTime() - now.getTime();

        // 如果当前期数已经过期或即将过期（剩余时间少于1分钟），执行轮转
        if (timeLeft <= 60000) {
          this.logger.log("⚠️ 发现赤壁玩法期数已过期或即将过期，执行轮转");
          await this.handleChibiRoundRotation();
        }
      }

      this.logger.log("✅ 重启期间错过的定时任务检查完成");
    } catch (error: any) {
      this.logger.error("❌ 处理错过的定时任务失败:", error?.message || error);
    }
  }

  /**
   * 重启时强制关闭所有活跃期数
   * 这个方法在服务启动后立即执行，强制关闭所有大小和赤壁期数，不管是否过期
   */
  private async forceCloseAllActiveRoundsOnRestart(): Promise<void> {
    try {
      this.logger.log("🔄 重启时强制关闭所有活跃期数...");

      // 1. 获取所有活跃的大小期数
      const activeDiceRounds = await this.diceRoundService.getAllActiveRounds();
      this.logger.log(`发现 ${activeDiceRounds.length} 个活跃的大小期数`);

      // 2. 获取所有活跃的赤壁期数
      const activeChibiRounds =
        await this.chibiRoundService.getAllActiveRounds();
      this.logger.log(`发现 ${activeChibiRounds.length} 个活跃的赤壁期数`);

      // 3. 强制关闭所有大小期数
      for (const round of activeDiceRounds) {
        try {
          await this.diceRoundService.updateRoundStatus(
            round.id,
            DiceRoundStatus.DRAWING
          ); // DRAWING状态（已结束）
          this.logger.log(`🔧 强制关闭大小期数 ${round.id}`);
        } catch (error: any) {
          this.logger.error(
            `❌ 强制关闭大小期数 ${round.id} 失败:`,
            error?.message || error
          );
        }
      }

      // 4. 强制关闭所有赤壁期数
      for (const round of activeChibiRounds) {
        try {
          await this.chibiRoundService.updateRoundStatus(
            round.id,
            ChibiRoundStatus.DRAWING
          ); // DRAWING状态（已结束）
          this.logger.log(`🔧 强制关闭赤壁期数 ${round.id}`);
        } catch (error: any) {
          this.logger.error(
            `❌ 强制关闭赤壁期数 ${round.id} 失败:`,
            error?.message || error
          );
        }
      }

      // 5. 等待一秒，确保数据库状态更新
      await new Promise((resolve) => setTimeout(resolve, 1000));

      // 6. 结算所有已关闭的期数
      await this.settleClosedDiceRounds();
      await this.settleClosedChibiRounds();

      this.logger.log("✅ 重启时强制关闭所有活跃期数完成");
    } catch (error: any) {
      this.logger.error(
        "❌ 重启时强制关闭所有活跃期数失败:",
        error?.message || error
      );
    }
  }

  /**
   * 处理重启后的期数状态恢复
   * 这个方法在服务启动后立即执行，确保期数状态正确
   */
  private async handleRestartRecovery(): Promise<void> {
    try {
      this.logger.log("🔄 开始处理重启后的期数状态恢复...");

      // 1. 检查并修复过期未结算的期数
      await this.recoverExpiredUnsettledRounds();

      // 2. 检查并修复未开始但已过期的期数
      await this.recoverExpiredUnstartedRounds();

      // 3. 确保有当前活跃期数
      await this.ensureActiveRoundsExist();

      this.logger.log("✅ 重启后的期数状态恢复完成");
    } catch (error: any) {
      this.logger.error(
        "❌ 重启后的期数状态恢复失败:",
        error?.message || error
      );
    }
  }

  /**
   * 恢复过期未结算的期数
   */
  private async recoverExpiredUnsettledRounds(): Promise<void> {
    try {
      this.logger.log("🔄 检查过期未结算的期数...");

      // 获取所有需要结算的期数
      const diceRoundsToSettle =
        await this.diceRoundService.getRoundsToSettle();
      const chibiRoundsToSettle =
        await this.chibiRoundService.getRoundsToSettle();

      if (diceRoundsToSettle.length > 0 || chibiRoundsToSettle.length > 0) {
        this.logger.log(
          `发现 ${diceRoundsToSettle.length} 个过期未结算的大小期数，${chibiRoundsToSettle.length} 个过期未结算的赤壁期数`
        );

        // 立即结算这些期数
        await this.settleClosedDiceRounds();
        await this.settleClosedChibiRounds();
      } else {
        this.logger.log("ℹ️ 没有发现过期未结算的期数");
      }
    } catch (error: any) {
      this.logger.error("❌ 恢复过期未结算期数失败:", error?.message || error);
    }
  }

  /**
   * 恢复过期未开始的期数
   */
  private async recoverExpiredUnstartedRounds(): Promise<void> {
    try {
      this.logger.log("🔄 检查过期未开始的期数...");

      const now = new Date();

      // 检查大小玩法：如果有未开始但已过期的期数，将其状态改为已结束
      const activeDiceRounds =
        await this.diceRoundService.getExpiredActiveRounds();
      for (const round of activeDiceRounds) {
        if (round.startTime > now) {
          // 期数还未开始但已过期，需要调整时间或删除
          this.logger.log(
            `⚠️ 发现过期未开始的大小期数 ${
              round.id
            }，开始时间: ${round.startTime.toISOString()}`
          );

          // 如果开始时间在未来，说明时间设置有问题，标记为已结束状态
          if (round.startTime > now) {
            await this.diceRoundService.updateRoundStatus(
              round.id,
              DiceRoundStatus.DRAWING
            ); // DRAWING状态（已结束）
            this.logger.log(
              `🔧 标记过期未开始的大小期数 ${round.id} 为已结束状态`
            );
          }
        }
      }

      // 检查赤壁玩法：如果有未开始但已过期的期数，将其状态改为已结束
      const activeChibiRounds =
        await this.chibiRoundService.getExpiredActiveRounds();
      for (const round of activeChibiRounds) {
        if (round.startTime > now) {
          // 期数还未开始但已过期，需要调整时间或删除
          this.logger.log(
            `⚠️ 发现过期未开始的赤壁期数 ${
              round.id
            }，开始时间: ${round.startTime.toISOString()}`
          );

          // 如果开始时间在未来，说明时间设置有问题，标记为已结束状态
          if (round.startTime > now) {
            await this.chibiRoundService.updateRoundStatus(
              round.id,
              ChibiRoundStatus.DRAWING
            ); // DRAWING状态（已结束）
            this.logger.log(
              `🔧 标记过期未开始的赤壁期数 ${round.id} 为已结束状态`
            );
          }
        }
      }
    } catch (error: any) {
      this.logger.error("❌ 恢复过期未开始期数失败:", error?.message || error);
    }
  }

  /**
   * 确保有当前活跃期数
   */
  private async ensureActiveRoundsExist(): Promise<void> {
    try {
      this.logger.log("🔄 确保有当前活跃期数...");

      // 检查大小玩法是否有当前期数
      const currentDiceRound = await this.diceRoundService.getCurrentRound();
      if (!currentDiceRound) {
        this.logger.log("🕐 大小玩法没有当前期数，立即创建新期数");
        await this.createNewDiceRounds();
        return;
      }

      // 检查赤壁玩法是否有当前期数
      const currentChibiRound = await this.chibiRoundService.getCurrentRound();
      if (!currentChibiRound) {
        this.logger.log("🕐 赤壁玩法没有当前期数，立即创建新期数");
        await this.createNewChibiRounds();
        return;
      }

      // 检查当前期数是否即将过期（剩余时间少于2分钟）
      const now = new Date();
      const diceTimeLeft = currentDiceRound.endTime.getTime() - now.getTime();
      const chibiTimeLeft = currentChibiRound.endTime.getTime() - now.getTime();

      if (diceTimeLeft < 120000 || chibiTimeLeft < 120000) {
        this.logger.log("⚠️ 当前期数即将过期，准备创建新期数");
        // 立即创建新期数，确保无缝衔接
        await this.createNewDiceRounds();
        await this.createNewChibiRounds();
      } else {
        this.logger.log(
          `✅ 当前期数状态正常，大小玩法剩余 ${Math.floor(
            diceTimeLeft / 1000
          )}秒，赤壁玩法剩余 ${Math.floor(chibiTimeLeft / 1000)}秒`
        );
      }

      // 检查并调整期数时间，确保重启后的时间连续性
      await this.adjustRoundTimesForContinuity();
    } catch (error: any) {
      this.logger.error("❌ 确保活跃期数存在失败:", error?.message || error);
    }
  }

  /**
   * 调整期数时间以确保连续性
   * 这个方法处理重启后可能的时间不连续问题
   */
  private async adjustRoundTimesForContinuity(): Promise<void> {
    try {
      this.logger.log("🔄 检查期数时间连续性...");

      const now = new Date();

      // 检查大小玩法期数时间
      const currentDiceRound = await this.diceRoundService.getCurrentRound();
      if (currentDiceRound) {
        // 如果当前期数的开始时间在未来，说明时间设置有问题
        if (currentDiceRound.startTime > now) {
          this.logger.log(
            `⚠️ 大小玩法当前期数开始时间在未来: ${currentDiceRound.startTime.toISOString()}`
          );

          // 调整开始时间为当前时间
          const newStartTime = new Date();
          const newEndTime = new Date(newStartTime.getTime() + 10 * 60 * 1000);

          // 更新期数时间
          await this.diceRoundService.updateRoundTimes(
            currentDiceRound.id,
            newStartTime,
            newEndTime
          );
          this.logger.log(
            `✅ 调整大小玩法期数 ${
              currentDiceRound.id
            } 时间: 开始=${newStartTime.toISOString()}, 结束=${newEndTime.toISOString()}`
          );
        }
      }

      // 检查赤壁玩法期数时间
      const currentChibiRound = await this.chibiRoundService.getCurrentRound();
      if (currentChibiRound) {
        // 如果当前期数的开始时间在未来，说明时间设置有问题
        if (currentChibiRound.startTime > now) {
          this.logger.log(
            `⚠️ 赤壁玩法当前期数开始时间在未来: ${currentChibiRound.startTime.toISOString()}`
          );

          // 调整开始时间为当前时间
          const newStartTime = new Date();
          const newEndTime = new Date(newStartTime.getTime() + 10 * 60 * 1000);

          // 更新期数时间
          await this.chibiRoundService.updateRoundTimes(
            currentChibiRound.id,
            newStartTime,
            newEndTime
          );
          this.logger.log(
            `✅ 调整赤壁玩法期数 ${
              currentChibiRound.id
            } 时间: 开始=${newStartTime.toISOString()}, 结束=${newEndTime.toISOString()}`
          );
        }
      }

      this.logger.log("✅ 期数时间连续性检查完成");
    } catch (error: any) {
      this.logger.error("❌ 调整期数时间连续性失败:", error?.message || error);
    }
  }

  /**
   * 每10分钟执行大小玩法期数轮转
   * 严格按照顺序执行：1.关闭 -> 2.开奖 -> 3.结算 -> 4.创建新期数
   */
  @Cron(CronExpression.EVERY_10_MINUTES)
  async handleDiceRoundRotation() {
    const disableScheduler = process.env.DISABLE_CASINO_SCHEDULER === "true";

    if (disableScheduler) {
      this.logger.log(
        "🔄 开发环境====娱乐城定时任务调度器已禁用，跳过大小玩法期数轮转任务"
      );
      return;
    }

    if (this.isDiceProcessing) {
      this.logger.warn("⚠️ 大小玩法期数轮转任务正在执行中，跳过本次执行");
      return;
    }

    this.isDiceProcessing = true;
    try {
      this.logger.log("🔄 开始执行大小玩法期数轮转任务");

      // 1. 先关闭：获取最后一个下注中的期数并关闭
      const currentDiceRound = await this.diceRoundService.getCurrentRound();

      if (!currentDiceRound) {
        this.logger.log("ℹ️ 没有活跃的大小期数，跳过步骤1-3，直接创建新期数");
        // 直接创建新期数
        await this.createNewDiceRounds();
        return;
      }

      this.logger.log(`发现当前大小期数 ${currentDiceRound.id}，开始处理`);

      // 1. 关闭：修改状态为开奖中（无论是否到时间，只要是下注中的状态）
      await this.diceRoundService.updateRoundStatus(
        currentDiceRound.id,
        DiceRoundStatus.DRAWING
      );
      this.logger.log(
        `✅ 步骤1-关闭：期数 ${currentDiceRound.id} 状态已修改为开奖中`
      );

      // 2. 开奖：生成开奖结果并保存
      const diceResult = this.generateDiceResult();
      await this.diceRoundService.updateRoundResult(
        currentDiceRound.id,
        diceResult
      );
      this.logger.log(
        `✅ 步骤2-开奖：期数 ${currentDiceRound.id} 开奖完成: ${
          diceResult.num1
        },${diceResult.num2},${diceResult.num3} (${diceResult.sum}点${
          diceResult.isBig ? "大" : "小"
        }${diceResult.isOdd ? "单" : "双"}${diceResult.isTriple ? "豹子" : ""})`
      );

      // 3. 结算：结算当前期数
      await this.settlementService.settleDiceRound(currentDiceRound.id);
      this.logger.log(`✅ 步骤3-结算：期数 ${currentDiceRound.id} 结算完成`);

      // 4. 创建新期数
      await this.createNewDiceRounds();
      this.logger.log(`✅ 步骤4-创建：新期数创建完成`);

      this.logger.log("✅ 大小玩法期数轮转任务执行完成");
    } catch (error: any) {
      this.logger.error(
        "❌ 大小玩法期数轮转任务执行失败:",
        error?.message || error
      );
    } finally {
      this.isDiceProcessing = false;
    }
  }

  /**
   * 每10分钟执行赤壁玩法期数轮转
   * 严格按照顺序执行：1.关闭 -> 2.开奖 -> 3.结算 -> 4.创建新期数
   */
  @Cron(CronExpression.EVERY_10_MINUTES)
  async handleChibiRoundRotation() {
    const disableScheduler = process.env.DISABLE_CASINO_SCHEDULER === "true";

    if (disableScheduler) {
      this.logger.log(
        "🔄 开发环境====娱乐城定时任务调度器已禁用，跳过赤壁玩法期数轮转任务"
      );
      return;
    }

    if (this.isChibiProcessing) {
      this.logger.warn("⚠️ 赤壁玩法期数轮转任务正在执行中，跳过本次执行");
      return;
    }

    this.isChibiProcessing = true;
    try {
      this.logger.log("🔄 开始执行赤壁玩法期数轮转任务");

      // 1. 先关闭：获取最后一个下注中的期数并关闭
      const currentChibiRound = await this.chibiRoundService.getCurrentRound();

      if (!currentChibiRound) {
        this.logger.log("ℹ️ 没有活跃的赤壁期数，跳过步骤1-3，直接创建新期数");
        // 直接创建新期数
        await this.createNewChibiRounds();
        return;
      }

      this.logger.log(`发现当前赤壁期数 ${currentChibiRound.id}，开始处理`);

      // 1. 关闭：修改状态为开奖中（无论是否到时间，只要是下注中的状态）
      await this.chibiRoundService.updateRoundStatus(
        currentChibiRound.id,
        ChibiRoundStatus.DRAWING
      );
      this.logger.log(
        `✅ 步骤1-关闭：期数 ${currentChibiRound.id} 状态已修改为开奖中`
      );

      // 2. 开奖：生成开奖结果并保存
      const chibiResult = this.generateChibiResult();
      await this.chibiRoundService.updateRoundResult(
        currentChibiRound.id,
        chibiResult
      );

      const sideNames: { [key: number]: string } = {
        1: "魏国",
        2: "蜀国",
        3: "吴国",
      };
      this.logger.log(
        `✅ 步骤2-开奖：期数 ${currentChibiRound.id} 开奖完成: ${
          sideNames[chibiResult.winningSide]
        }获胜 - ${chibiResult.battleReport}`
      );

      // 3. 结算：结算当前期数
      await this.settlementService.settleChibiRound(currentChibiRound.id);
      this.logger.log(`✅ 步骤3-结算：期数 ${currentChibiRound.id} 结算完成`);

      // 4. 创建新期数
      await this.createNewChibiRounds();
      this.logger.log(`✅ 步骤4-创建：新期数创建完成`);

      this.logger.log("✅ 赤壁玩法期数轮转任务执行完成");
    } catch (error: any) {
      this.logger.error(
        "❌ 赤壁玩法期数轮转任务执行失败:",
        error?.message || error
      );
    } finally {
      this.isChibiProcessing = false;
    }
  }

  /**
   * 每天凌晨2点清理过期数据
   */
  @Cron("0 2 * * *")
  async handleDataCleanup() {
    try {
      this.logger.log("🧹 开始清理过期数据");
      const [diceCount, chibiCount] = await Promise.all([
        this.diceRoundService.cleanupExpiredRounds(30),
        this.chibiRoundService.cleanupExpiredRounds(30),
      ]);

      this.logger.log(
        `✅ 数据清理完成：大小玩法 ${diceCount} 条，赤壁玩法 ${chibiCount} 条`
      );
    } catch (error: any) {
      this.logger.error("❌ 数据清理失败:", error?.message || error);
    }
  }

  /**
   * 每小时执行健康检查
   */
  @Cron("0 * * * *")
  async handleHealthCheck() {
    try {
      this.logger.log("🏥 开始健康检查");

      // 检查数据库连接
      const dbHealth = await this.checkDatabaseHealth();
      // 检查Redis连接
      const redisHealth = await this.checkRedisHealth();
      // 检查游戏状态
      const gameHealth = await this.checkGameHealth();

      if (dbHealth && redisHealth && gameHealth) {
        this.logger.log("✅ 健康检查通过");
      } else {
        this.logger.warn("⚠️ 健康检查发现问题");
      }
    } catch (error: any) {
      this.logger.error("❌ 健康检查失败:", error?.message || error);
    }
  }

  /**
   * 关闭过期的大小期数
   */
  private async closeExpiredDiceRounds(): Promise<void> {
    try {
      this.logger.log("🔄 开始关闭过期大小期数");

      const expiredDiceRounds =
        await this.diceRoundService.getExpiredActiveRounds();

      if (expiredDiceRounds.length > 0) {
        this.logger.log(`发现 ${expiredDiceRounds.length} 个过期大小期数`);

        // 关闭过期的大小期数并生成开奖结果
        for (const round of expiredDiceRounds) {
          try {
            // 生成开奖结果
            const diceResult = this.generateDiceResult();

            // 更新期数状态为开奖中
            await this.diceRoundService.updateRoundStatus(
              round.id,
              DiceRoundStatus.DRAWING // DRAWING状态
            );

            // 保存开奖结果到数据库
            await this.diceRoundService.updateRoundResult(round.id, diceResult);

            this.logger.log(
              `🔧 强制关闭过期大小期数 ${round.id}，开奖结果: ${
                diceResult.num1
              },${diceResult.num2},${diceResult.num3} (${diceResult.sum}点${
                diceResult.isBig ? "大" : "小"
              }${diceResult.isOdd ? "单" : "双"}${
                diceResult.isTriple ? "豹子" : ""
              })`
            );
          } catch (error: any) {
            this.logger.error(
              `❌ 强制关闭过期大小期数 ${round.id} 失败:`,
              error?.message || error
            );
          }
        }
      } else {
        this.logger.log("ℹ️ 没有发现过期的大小期数");
      }
    } catch (error: any) {
      this.logger.error("❌ 关闭过期大小期数失败:", error?.message || error);
    }
  }

  /**
   * 关闭过期的赤壁期数
   */
  private async closeExpiredChibiRounds(): Promise<void> {
    try {
      this.logger.log("🔄 开始关闭过期赤壁期数");

      const expiredChibiRounds =
        await this.chibiRoundService.getExpiredActiveRounds();

      if (expiredChibiRounds.length > 0) {
        this.logger.log(`发现 ${expiredChibiRounds.length} 个过期赤壁期数`);

        // 关闭过期的赤壁期数并生成开奖结果
        for (const round of expiredChibiRounds) {
          try {
            // 生成开奖结果
            const chibiResult = this.generateChibiResult();

            // 更新期数状态为开奖中
            await this.chibiRoundService.updateRoundStatus(
              round.id,
              ChibiRoundStatus.DRAWING // DRAWING状态
            );

            // 保存开奖结果到数据库
            await this.chibiRoundService.updateRoundResult(
              round.id,
              chibiResult
            );

            const sideNames: { [key: number]: string } = {
              1: "魏国",
              2: "蜀国",
              3: "吴国",
            };
            this.logger.log(
              `🔧 强制关闭过期赤壁期数 ${round.id}，开奖结果: ${
                sideNames[chibiResult.winningSide]
              }获胜 - ${chibiResult.battleReport}`
            );
          } catch (error: any) {
            this.logger.error(
              `❌ 强制关闭过期赤壁期数 ${round.id} 失败:`,
              error?.message || error
            );
          }
        }
      } else {
        this.logger.log("ℹ️ 没有发现过期的赤壁期数");
      }
    } catch (error: any) {
      this.logger.error("❌ 关闭过期赤壁期数失败:", error?.message || error);
    }
  }

  /**
   * 结算已关闭的大小期数
   */
  private async settleClosedDiceRounds(): Promise<void> {
    try {
      this.logger.log("🔄 开始结算已关闭的大小期数");

      const diceRoundsToSettle =
        await this.diceRoundService.getRoundsToSettle();

      if (diceRoundsToSettle.length > 0) {
        this.logger.log(`发现 ${diceRoundsToSettle.length} 个大小期数需要结算`);

        // 结算大小期数
        for (const round of diceRoundsToSettle) {
          try {
            if (round.num1 && round.num2 && round.num3) {
              await this.settlementService.settleDiceRound(round.id);
            } else {
              //没有开奖信息不结算
              this.logger.log(`✅ 大小期数 ${round.id} 没有开奖信息，不结算`);
            }
            this.logger.log(`✅ 大小期数 ${round.id} 结算完成`);
          } catch (error: any) {
            this.logger.error(
              `❌ 结算大小期数 ${round.id} 失败:`,
              error?.message || error
            );
          }
        }
      } else {
        this.logger.log("ℹ️ 没有需要结算的大小期数");
      }
    } catch (error: any) {
      this.logger.error("❌ 结算已关闭大小期数失败:", error?.message || error);
    }
  }

  /**
   * 结算已关闭的赤壁期数
   */
  private async settleClosedChibiRounds(): Promise<void> {
    try {
      this.logger.log("🔄 开始结算已关闭的赤壁期数");

      const chibiRoundsToSettle =
        await this.chibiRoundService.getRoundsToSettle();

      if (chibiRoundsToSettle.length > 0) {
        this.logger.log(
          `发现 ${chibiRoundsToSettle.length} 个赤壁期数需要结算`
        );

        // 结算赤壁期数
        for (const round of chibiRoundsToSettle) {
          try {
            if (round.winningSide) {
              await this.settlementService.settleChibiRound(round.id);
              this.logger.log(`✅ 赤壁期数 ${round.id} 结算完成`);
            } else {
              //没有开奖信息不结算
              this.logger.log(`✅ 赤壁期数 ${round.id} 没有开奖信息，不结算`);
            }
          } catch (error: any) {
            this.logger.error(
              `❌ 结算赤壁期数 ${round.id} 失败:`,
              error?.message || error
            );
          }
        }
      } else {
        this.logger.log("ℹ️ 没有需要结算的赤壁期数");
      }
    } catch (error: any) {
      this.logger.error("❌ 结算已关闭赤壁期数失败:", error?.message || error);
    }
  }

  /**
   * 创建新的大小期数
   */
  private async createNewDiceRounds(): Promise<void> {
    try {
      this.logger.log("🕐 开始创建新的大小期数");

      const currentDiceRound = await this.diceRoundService.getCurrentRound();
      if (!currentDiceRound) {
        // 简化逻辑：开始时间直接设置为当前时间，结束时间为当前时间+10分钟
        const now = new Date();
        const nowUTC = new Date(
          Date.UTC(
            now.getUTCFullYear(),
            now.getUTCMonth(),
            now.getUTCDate(),
            now.getUTCHours(),
            now.getUTCMinutes(),
            now.getUTCSeconds(),
            now.getUTCMilliseconds()
          )
        );

        const startTime = nowUTC;
        const endTime = new Date(startTime.getTime() + 10 * 60 * 1000);

        await this.diceRoundService.createNewRound(startTime, endTime);
        this.logger.log(
          `✅ 创建大小玩法新期数，开始时间: ${startTime.toISOString()}，结束时间: ${endTime.toISOString()}，期数时长: 10分钟`
        );
      } else {
        this.logger.log("ℹ️ 大小玩法已有当前期数，跳过创建");
      }
    } catch (error: any) {
      this.logger.error("❌ 创建大小玩法期数失败:", error?.message || error);
      throw error;
    }
  }

  /**
   * 创建新的赤壁期数
   */
  private async createNewChibiRounds(): Promise<void> {
    try {
      this.logger.log("🕐 开始创建新的赤壁期数");

      const currentChibiRound = await this.chibiRoundService.getCurrentRound();

      if (!currentChibiRound) {
        // 简化逻辑：开始时间直接设置为当前时间，结束时间为当前时间+10分钟
        const now = new Date();
        const nowUTC = new Date(
          Date.UTC(
            now.getUTCFullYear(),
            now.getUTCMonth(),
            now.getUTCDate(),
            now.getUTCHours(),
            now.getUTCMinutes(),
            now.getUTCSeconds(),
            now.getUTCMilliseconds()
          )
        );

        const startTime = nowUTC;
        const endTime = new Date(startTime.getTime() + 10 * 60 * 1000);

        await this.chibiRoundService.createNewRound(startTime, endTime);
        this.logger.log(
          `✅ 创建赤壁玩法新期数，开始时间: ${startTime.toISOString()}，结束时间: ${endTime.toISOString()}，期数时长: 10分钟`
        );
      } else {
        this.logger.log("ℹ️ 赤壁玩法已有当前期数，跳过创建");
      }
    } catch (error: any) {
      this.logger.error("❌ 创建赤壁玩法期数失败:", error?.message || error);
      throw error;
    }
  }

  /**
   * 获取游戏类型名称
   */
  private getGameTypeName(gameType: number): string {
    switch (gameType) {
      case GameType.DICE:
        return "大小玩法";
      case GameType.CHIBI:
        return "赤壁玩法";
      case GameType.ROCK_PAPER_SCISSORS:
        return "猜拳玩法";
      default:
        return `未知类型(${gameType})`;
    }
  }

  /**
   * 检查数据库健康状态
   */
  private async checkDatabaseHealth(): Promise<boolean> {
    try {
      // 这里应该实现实际的数据库连接检查
      // 暂时返回true
      return true;
    } catch (error) {
      return false;
    }
  }

  /**
   * 检查Redis健康状态
   */
  private async checkRedisHealth(): Promise<boolean> {
    try {
      // 这里应该实现实际的Redis连接检查
      // 暂时返回true
      return true;
    } catch (error) {
      return false;
    }
  }

  /**
   * 检查游戏健康状态
   */
  private async checkGameHealth(): Promise<boolean> {
    try {
      // 检查是否有异常的游戏状态
      const expiredActiveRounds =
        await this.diceRoundService.getExpiredActiveRounds();

      if (expiredActiveRounds.length > 0) {
        this.logger.warn(
          `⚠️ 发现 ${expiredActiveRounds.length} 个已过期但仍在下注状态的期数`
        );
        return false;
      }

      return true;
    } catch (error) {
      return false;
    }
  }

  /**
   * 手动触发期数轮转（管理用）
   */
  async manuallyTriggerRoundRotation() {
    try {
      this.logger.log("🔄 手动触发期数轮转");
      await this.handleDiceRoundRotation();
      await this.handleChibiRoundRotation();
      return { success: true, message: "期数轮转完成" };
    } catch (error: any) {
      this.logger.error("❌ 手动期数轮转失败:", error?.message || error);
      return { success: false, message: error?.message || "轮转失败" };
    }
  }

  /**
   * 手动触发创建新期数（管理用）
   */
  async manuallyCreateRounds() {
    try {
      this.logger.log("🔄 手动触发创建新期数");
      await this.createNewDiceRounds();
      await this.createNewChibiRounds();
      return { success: true, message: "新期数创建完成" };
    } catch (error: any) {
      this.logger.error("❌ 手动创建期数失败:", error?.message || error);
      return { success: false, message: error?.message || "创建失败" };
    }
  }

  /**
   * 手动触发关闭期数（管理用）
   */
  async manuallyCloseRounds() {
    try {
      this.logger.log("🔄 手动触发关闭期数");
      await this.closeExpiredDiceRounds();
      await this.closeExpiredChibiRounds();
      return { success: true, message: "期数关闭完成" };
    } catch (error: any) {
      this.logger.error("❌ 手动关闭期数失败:", error?.message || error);
      return { success: false, message: error?.message || "关闭失败" };
    }
  }

  /**
   * 手动触发结算（管理用）
   */
  async manuallyTriggerSettlement() {
    try {
      this.logger.log("🔄 手动触发结算");
      await this.settleClosedDiceRounds();
      await this.settleClosedChibiRounds();
      return { success: true, message: "结算完成" };
    } catch (error: any) {
      this.logger.error("❌ 手动结算失败:", error?.message || error);
      return { success: false, message: error?.message || "结算失败" };
    }
  }

  /**
   * 手动触发数据清理（管理用）
   */
  async manuallyTriggerCleanup() {
    try {
      this.logger.log("🔄 手动触发数据清理");
      await this.handleDataCleanup();
      return { success: true, message: "数据清理完成" };
    } catch (error: any) {
      this.logger.error("❌ 手动数据清理失败:", error?.message || error);
      return { success: false, message: error?.message || "清理失败" };
    }
  }

  /**
   * 手动修复过期期数（紧急修复用）
   */
  async manuallyFixExpiredRounds() {
    try {
      this.logger.log("🔧 手动修复过期期数");

      // 先关闭过期期数
      await this.closeExpiredDiceRounds();
      await this.closeExpiredChibiRounds();

      // 等待一秒后开始结算
      await new Promise((resolve) => setTimeout(resolve, 1000));

      // 开始结算
      await this.settleClosedDiceRounds();
      await this.settleClosedChibiRounds();

      return { success: true, message: "过期期数修复完成" };
    } catch (error: any) {
      this.logger.error("❌ 手动修复过期期数失败:", error?.message || error);
      return { success: false, message: error?.message || "修复失败" };
    }
  }

  /**
   * 手动修复指定期数的开奖结果（紧急修复用）
   */
  async manuallyFixRoundResult(roundId: number, gameType: "dice" | "chibi") {
    try {
      this.logger.log(`🔧 手动修复期数 ${roundId} 的开奖结果 (${gameType})`);

      if (gameType === "dice") {
        // 检查期数状态
        const round = await this.diceRoundService.getRoundById(roundId);
        if (!round) {
          return { success: false, message: "期数不存在" };
        }

        if (round.status !== DiceRoundStatus.DRAWING) {
          return {
            success: false,
            message: `期数状态不是开奖中，当前状态: ${round.status}`,
          };
        }

        // 检查是否已有开奖结果
        if (round.num1 && round.num2 && round.num3) {
          return { success: false, message: "期数已有开奖结果" };
        }

        // 生成开奖结果
        const diceResult = this.generateDiceResult();
        await this.diceRoundService.updateRoundResult(roundId, diceResult);

        this.logger.log(
          `✅ 期数 ${roundId} 开奖结果修复完成: ${diceResult.num1},${diceResult.num2},${diceResult.num3}`
        );

        return {
          success: true,
          message: `期数 ${roundId} 开奖结果修复完成: ${diceResult.num1},${diceResult.num2},${diceResult.num3}`,
        };
      } else if (gameType === "chibi") {
        // 检查期数状态
        const round = await this.chibiRoundService.getRoundById(roundId);
        if (!round) {
          return { success: false, message: "期数不存在" };
        }

        if (round.status !== ChibiRoundStatus.DRAWING) {
          return {
            success: false,
            message: `期数状态不是开奖中，当前状态: ${round.status}`,
          };
        }

        // 检查是否已有开奖结果
        if (round.winningSide) {
          return { success: false, message: "期数已有开奖结果" };
        }

        // 生成开奖结果
        const chibiResult = this.generateChibiResult();
        await this.chibiRoundService.updateRoundResult(roundId, chibiResult);

        const sideNames: { [key: number]: string } = {
          1: "魏国",
          2: "蜀国",
          3: "吴国",
        };
        this.logger.log(
          `✅ 期数 ${roundId} 开奖结果修复完成: ${
            sideNames[chibiResult.winningSide]
          }获胜`
        );

        return {
          success: true,
          message: `期数 ${roundId} 开奖结果修复完成: ${
            sideNames[chibiResult.winningSide]
          }获胜`,
        };
      }

      return { success: false, message: "无效的游戏类型" };
    } catch (error: any) {
      this.logger.error(
        `❌ 手动修复期数 ${roundId} 开奖结果失败:`,
        error?.message || error
      );
      return { success: false, message: error?.message || "修复失败" };
    }
  }

  /**
   * 手动强制关闭所有活跃期数（紧急修复用）
   */
  async manuallyForceCloseAllActiveRounds() {
    try {
      this.logger.log("🔧 手动强制关闭所有活跃期数");
      await this.forceCloseAllActiveRoundsOnRestart();
      return { success: true, message: "强制关闭所有活跃期数完成" };
    } catch (error: any) {
      this.logger.error(
        "❌ 手动强制关闭所有活跃期数失败:",
        error?.message || error
      );
      return { success: false, message: error?.message || "强制关闭失败" };
    }
  }

  /**
   * 生成大小玩法开奖结果
   */
  private generateDiceResult(): any {
    const num1 = Math.floor(Math.random() * 6) + 1;
    const num2 = Math.floor(Math.random() * 6) + 1;
    const num3 = Math.floor(Math.random() * 6) + 1;

    const sum = num1 + num2 + num3;
    const isBig = sum > 10;
    const isSmall = sum <= 10;
    const isOdd = sum % 2 === 1;
    const isEven = sum % 2 === 0;
    const isTriple = num1 === num2 && num2 === num3;

    return {
      num1,
      num2,
      num3,
      sum,
      isBig,
      isSmall,
      isOdd,
      isEven,
      isTriple,
    };
  }

  /**
   * 生成赤壁玩法开奖结果
   */
  private generateChibiResult(): any {
    // 平等概率随机选择获胜国家（1/3概率）
    const winningSide = Math.floor(Math.random() * 3) + 1;

    // 生成战报描述
    const battleReports: { [key: number]: string[] } = {
      1: [
        "魏军大获全胜，曹操统一天下！",
        "魏国铁骑横扫千军，威震四方！",
        "曹操智谋过人，魏军势如破竹！",
      ],
      2: [
        "蜀汉复兴，刘备重振汉室！",
        "蜀国义军奋勇杀敌，光复中原！",
        "刘备仁德感天，蜀军所向披靡！",
      ],
      3: [
        "东吴水军无敌，孙权称霸江东！",
        "吴国水师乘风破浪，威震江南！",
        "孙权英明神武，吴军战无不胜！",
      ],
    };

    const reports = battleReports[winningSide];
    const battleReport = reports[Math.floor(Math.random() * reports.length)];

    return {
      winningSide,
      battleReport,
      sideStats: { 1: 0, 2: 0, 3: 0 }, // 简化版，不统计下注
      reportStr: battleReport,
    };
  }
}
